package cn.hhit.workflow.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.alibaba.fastjson.JSON;

import cn.hhit.common.action.CommonAction;
import cn.hhit.common.util.ListUtil;
import cn.hhit.school.service.PlanMainService;
import cn.hhit.system.model.DictDetail;
import cn.hhit.system.service.DictDetailService;
import cn.hhit.workflow.model.ActionInfo;
import cn.hhit.workflow.model.ActionInstant;
import cn.hhit.workflow.model.FlowInfo;
import cn.hhit.workflow.model.FlowInstant;
import cn.hhit.workflow.model.FlowWorks;
import cn.hhit.workflow.service.ActionInfoService;
import cn.hhit.workflow.service.ActionInstantService;
import cn.hhit.workflow.service.FlowInfoService;
import cn.hhit.workflow.service.FlowInstantService;
import cn.hhit.workflow.service.FlowWorksService;

@SuppressWarnings("rawtypes")
public class WorkFlowAction extends CommonAction {
	private static final long serialVersionUID = 1L;

	@Autowired
	@Qualifier("FlowInfoService")
	private FlowInfoService flowInfoService;

	@Autowired
	@Qualifier("FlowWorksService")
	private FlowWorksService flowWorksService;

	@Autowired
	@Qualifier("ActionInfoService")
	private ActionInfoService actionInfoService;

	@Autowired
	@Qualifier("FlowInstantService")
	private FlowInstantService flowInstantService;

	@Autowired
	@Qualifier("ActionInstantService")
	private ActionInstantService actionInstantService;

	@Autowired
	@Qualifier("PlanMainService")
	private PlanMainService planMainService;

	@Autowired
	@Qualifier("DictDetailService")
	private DictDetailService dictDetailService;

	private FlowInfo flow;
	private ActionInfo action;
	private ActionInstant actionis;
	private int flowid;
	private int actionid;
	private String flowname;
	private String gridJson;
	private int instantid;
	public int[] delIds;
	public int[] saveIds;
	public int step;

	public String pickUserToFlow() {
		return "pickusers";
	}

	public String showActionInfos() {
		return "actioninfos";
	}

	public String showFlows() {
		return "showflows";
	}

	public String showWorks() {
		return "showworks";
	}

	public void showSubmitInfo() {
		if (instantid != 0) {
			FlowInstant fi = flowInstantService.getUnique(" where instantid=?", instantid);
			if (fi != null) {
				FlowInfo fif = flowInfoService.get(fi.getFlowid());
				if (fif != null) {
					DictDetail dd = dictDetailService.getUnique(" where detailname=?", fif.getName());
					if (dd != null) {
						writeStringToClient(response, dd.getHasChild() + instantid, true);
					}
				}
			}
		}

	}

	/*
	 * 编辑流程信息，查找流程信息
	 */
	public void findFlowInfo() {
		FlowInfo fi = flowInfoService.get(flowid);
		writeObjectToClient(response, fi, true);
	}

	/*
	 * 停止使用流程信息
	 */
	public void stopFLowInfo() {
		if (delIds != null) {
			for (int i = 0; i < delIds.length; i++) {
				flowInfoService.update(" set state='saved',inuse='否' where id=?", delIds[i]);
			}
		}
		writeResultToClient(response, true);
	}

	/*
	 * 保存流程信息
	 */
	public void saveFLowInfo() {
		if (saveIds != null) {
			for (int i = 0; i < saveIds.length; i++) {
				flowInfoService.update(" set state='saved' where id=?", saveIds[i]);
			}
		}
		writeResultToClient(response, true);
	}

	/*
	 * 退回后再次提交
	 */
	public void submitAgain() {
		// 复制退回的节点（节点标记是rollback，复制完后将节点标记去除）
		ActionInstant ai = actionInstantService.getUnique(" where instantid=? and pass='否' and rollback='rollback'",
				instantid);
		if (ai != null) {
			ActionInstant ainew = new ActionInstant();
			BeanUtils.copyProperties(ai, ainew);
			ainew.setId(0);
			ainew.setRollback("submit");// 退回后又提交，pass是否，rollback是submit
			ainew.setPass("");
			ainew.setResult("");
			ainew.setHandledate(null);
			actionInstantService.save(ainew);
			// 将流程的currentStep指向该新节点
			// FlowInstant fi = flowInstantService.get(ai.getFlowid());
			// fi.setCurrentstep(ainew.getId());
			// flowInstantService.saveOrUpdate(fi);
			flowInstantService.update(" set currentstep=? where id=?", ainew.getId(), ai.getFlowid());

			// 将rollback节点标记去除，开始新的流程
			actionInstantService.update(" set rollback='' where id=?", ai.getId());
			// actionInstantService.update(" set pass='退回后提交' where instantid=?
			// and pass='否'", instantid);
			flowInstantService.updateState(" " + instantClass + " set state=3 where id=?", instantid);// 退回后提交状态为3
		}
		writeResultToClient(response, true);
	}

	public void findActionInstant() {
		ActionInstant ai = actionInstantService.get(actionid);
		writeObjectToClient(response, ai, true);
	}

	public void countMyWorks() {
		Object userido = session.get("uid");
		String userids = "";
		if (userido == null) {
			writeResultToClient(response, false);
		} else {
			userids = userido.toString();
			List<FlowWorks> fwList = flowWorksService
					.listByParams(" where opratorid=? and (pass is null or pass='' or rollback='submit')", userids);
			if (fwList != null) {
				writeStringToClient(response, "您有" + fwList.size() + "条待办任务", true);
			}
		}
	}

	public void listMyWorks() {
		Object userido = session.get("uid");
		String userids = "";
		if (userido == null) {
			writeResultToClient(response, false);
		} else {
			userids = userido.toString();
			List<FlowInstant> fiList = flowInstantService.listAll();
			List<ActionInstant> aiList = new ArrayList<ActionInstant>();

			if (ListUtil.filterList(fiList)) {
				for (FlowInstant fi : fiList) {
					ActionInstant ai = actionInstantService.get(fi.getCurrentstep());
					if (userids.equals(ai.getOpratorid())
							&& (ai.getPass() == null || "".equals(ai.getPass()) || "submit".equals(ai.getRollback()))) {
						aiList.add(ai);
					}
				}
			}
			writeListToClient(response, aiList, true);
		}
	}

	/*
	 * 判断流程名是否重复，停止使用的不包括在内
	 */
	public void uniqueFlowJudge() {
		FlowInfo fi = flowInfoService.getUnique(" where name=? and state<>'saved' ", flowname);
		if (fi != null) {
			writeResultToClient(response, false);
		} else {
			writeResultToClient(response, true);
		}
	}

	public void uniqueActionJudge() {
		ActionInfo ai = actionInfoService.getUnique(" where step=? and flowid=?", step, flowid);
		if (ai != null) {
			writeResultToClient(response, false);
		} else {
			writeResultToClient(response, true);
		}
	}

	public void submitApprove() {
		FlowInfo fi = flowInfoService.getUnique(" where name=?", flowname);
		FlowInstant finstant = new FlowInstant();
		finstant.setFlowid(fi.getId());
		finstant.setInstantid(instantid);
		flowInstantService.saveOrUpdate(finstant);

		List<ActionInstant> ainstantList = JSON.parseArray(gridJson, ActionInstant.class);
		if (ListUtil.filterList(ainstantList)) {
			for (ActionInstant ainstant : ainstantList) {
				ainstant.setId(0);
				ainstant.setFlowid(finstant.getId());
				ainstant.setInstantid(finstant.getInstantid());
				ainstant.setInstantclass(instantClass);
				actionInstantService.saveOrUpdate(ainstant);
			}
			List<ActionInstant> aiList = actionInstantService.listByParams(" where flowid=? order by step",
					finstant.getId());
			if (ListUtil.filterList(aiList)) {
				for (int i = 0; i < aiList.size(); i++) {
					ActionInstant ai = aiList.get(i);
					if (i == 0) {
						ai.setPre(-1);
						finstant.setCurrentstep(ai.getId());
						flowInstantService.saveOrUpdate(finstant);
					} else {
						ai.setPre(aiList.get(i - 1).getId());
					}
					if (i == aiList.size() - 1) {
						ai.setNext(-1);
					} else {
						ai.setNext(aiList.get(i + 1).getId());
					}
					actionInstantService.saveOrUpdate(ai);
				}
			}
		}
		flowInstantService.updateState(" " + instantClass + " set state=1 where id=?", instantid);
		writeResultToClient(response, true);
	}

	public void showActions() {
		List<FlowInstant> fiList = flowInstantService.listByParams(" where instantid=?", instantid);
		List<ActionInstant> aiList = new ArrayList<ActionInstant>();
		FlowInstant fi = new FlowInstant();
		if (fiList != null && !fiList.isEmpty()) {
			fi = fiList.get(0);
			aiList = actionInstantService.listByParams(" where flowid=? order by step", fi.getId());
		}
		writeListToClient(response, aiList, true);
	}

	public void flowList() {
		List<FlowInfo> fiList = flowInfoService.listAll();
		writeListToClient(response, fiList, true);
	}

	public void editFlowInfo() {
		flow.setCreatedate(new Date());
		flow.setCreateuser(session.get("fullname") == null ? "" : session.get("fullname").toString());
		flow.setInuse("是");
		flowInfoService.saveOrUpdate(flow);
		writeResultToClient(response, true);
	}

	public void editActionInfo() {
		action.setFlowid(flowid);
		actionInfoService.saveOrUpdate(action);
		List<ActionInfo> aiList = actionInfoService.listByParams(" where flowid=? order by step", flowid);
		if (aiList != null && !aiList.isEmpty()) {
			for (int i = 0; i < aiList.size(); i++) {
				ActionInfo ai = aiList.get(i);
				if (i == 0) {
					ai.setPre(-1);
				} else {
					ai.setPre(aiList.get(i - 1).getId());
				}
				if (i == aiList.size() - 1) {
					ai.setNext(-1);
				} else {
					ai.setNext(aiList.get(i + 1).getId());
				}
				actionInfoService.saveOrUpdate(ai);
			}
		}
		writeResultToClient(response, true);
	}

	public void checkActionInstant() {
		actionis.setHandledate(new Date());
		if ("是".equals(actionis.getPass())) {
			if (actionis.getNext() == -1) {
				// 审批结束，方案通过
				int instantid = actionis.getInstantid();
				flowInstantService.updateState(" " + actionis.getInstantclass() + " set state=2 where id=?", instantid);
			} else {
				// 审批的某个节点通过，转到下一个节点
				int nextid = actionis.getNext();
				FlowInstant fi = flowInstantService.get(actionis.getFlowid());
				fi.setCurrentstep(nextid);
				flowInstantService.saveOrUpdate(fi);
			}
		} else {
			// 审批不通过，方案退回;
			// 节点信息复制？当修改后再次提交时新增记录.当前节点的pass为否
			actionis.setRollback("rollback");
			actionInstantService.saveOrUpdate(actionis);
			int instantid = actionis.getInstantid();
			flowInstantService.updateState(" " + actionis.getInstantclass() + " set state=-1 where id=?", instantid);
		}
		actionInstantService.saveOrUpdate(actionis);
		writeResultToClient(response, true);
	}

	public void actionList() {
		List<ActionInfo> acList = new ArrayList<ActionInfo>();
		if (flowid != 0) {
			acList = actionInfoService.listByParams(" where flowid=? order by step", flowid);
		}
		writeListToClient(response, acList, true);
	}

	public void listActions() {
		List<ActionInfo> acList = new ArrayList<ActionInfo>();
		if (flowname != null) {
			List<FlowInfo> fiList = flowInfoService.listByParams(" where name=?", flowname);
			if (fiList != null && !fiList.isEmpty()) {
				FlowInfo fi = fiList.get(0);
				acList = actionInfoService.listByParams(" where flowid=?order by step", fi.getId());
			}
		}
		writeListToClient(response, acList, true);
	}

	/*
	 * 为流程节点选择用户，列出所有节点
	 */
	public void pickUserToActions() {
		List<ActionInfo> acList = new ArrayList<ActionInfo>();
		List<ActionInstant> aiList = new ArrayList<ActionInstant>();
		if (flowname != null) {
			List<FlowInfo> fiList = flowInfoService.listByParams(" where name=?", flowname);
			if (fiList != null && !fiList.isEmpty()) {
				FlowInfo fi = fiList.get(0);
				acList = actionInfoService.listByParams(" where flowid=?order by step", fi.getId());
			}
		}
		if (acList != null && !acList.isEmpty()) {
			for (ActionInfo ai : acList) {
				ActionInstant ainstant = new ActionInstant();
				ainstant.setId(ai.getId());
				ainstant.setName(ai.getName());
				ainstant.setOprator("");
				ainstant.setDescription(ai.getDescription());
				ainstant.setHandlertype(ai.getHandlertype());
				ainstant.setNext(ai.getNext());
				ainstant.setPre(ai.getPre());
				ainstant.setStep(ai.getStep());
				ainstant.setRoleid(ai.getRoleid());
				aiList.add(ainstant);
			}
		}
		writeListToClient(response, aiList, true);
	}

	public void delActionInfo() {
		if (delIds != null) {
			for (int i = 0; i < delIds.length; i++) {
				actionInfoService.delByParams(" where id=?", delIds[i]);
			}
		}
		List<ActionInfo> aiList = actionInfoService.listByParams(" where flowid=? order by step", flowid);
		if (aiList != null && !aiList.isEmpty()) {
			for (int i = 0; i < aiList.size(); i++) {
				ActionInfo ai = aiList.get(i);
				if (i == 0) {
					ai.setPre(-1);
				} else {
					ai.setPre(aiList.get(i - 1).getId());
				}
				if (i == aiList.size() - 1) {
					ai.setNext(-1);
				} else {
					ai.setNext(aiList.get(i + 1).getId());
				}
				actionInfoService.saveOrUpdate(ai);
			}
		}
		writeResultToClient(response, true);
	}

	public FlowInfo getFlow() {
		return flow;
	}

	public void setFlow(FlowInfo flow) {
		this.flow = flow;
	}

	public int getFlowid() {
		return flowid;
	}

	public void setFlowid(int flowid) {
		this.flowid = flowid;
	}

	public ActionInfo getAction() {
		return action;
	}

	public void setAction(ActionInfo action) {
		this.action = action;
	}

	public String getFlowname() {
		return flowname;
	}

	public void setFlowname(String flowname) {
		this.flowname = flowname;
	}

	public String getGridJson() {
		return gridJson;
	}

	public void setGridJson(String gridJson) {
		this.gridJson = gridJson;
	}

	public int getInstantid() {
		return instantid;
	}

	public void setInstantid(int instantid) {
		this.instantid = instantid;
	}

	public int[] getDelIds() {
		return delIds;
	}

	public void setDelIds(int[] delIds) {
		this.delIds = delIds;
	}

	public int getStep() {
		return step;
	}

	public void setStep(int step) {
		this.step = step;
	}

	public ActionInstant getActionis() {
		return actionis;
	}

	public void setActionis(ActionInstant actionis) {
		this.actionis = actionis;
	}

	public int getActionid() {
		return actionid;
	}

	public void setActionid(int actionid) {
		this.actionid = actionid;
	}

	public int[] getSaveIds() {
		return saveIds;
	}

	public void setSaveIds(int[] saveIds) {
		this.saveIds = saveIds;
	}

}
